package frequency

import (
	"sync"
	"time"
)

type TimeConf struct {
	Duration time.Duration
	Count    uint
}

// LogTime 日志时间数据
type LogTime struct {
	UniqueID string
	Time     time.Time
}

// Multistage 不同阶段频繁设置
type Multistage struct {
	TimeConfArr []TimeConf
	Logs        []LogTime
	logLock     sync.Mutex
}

// AppendLog 追回记录
// 使用时机
//
//	登录密码: 应在检查有可用次数之后添加
//	支付密码: 应在检查有可用次数且密码验证失败后再添加
func (o *Multistage) AppendLog(uniqueID string) {
	if o.Logs == nil {
		o.Logs = []LogTime{}
	}
	o.logLock.Lock()
	o.Logs = append(o.Logs, LogTime{
		UniqueID: uniqueID,
		Time:     time.Now(),
	})
	o.logLock.Unlock()
}

// CheckCount 检查可用次数
func (o *Multistage) CheckCount(uniqueID string) (uint, time.Time) {
	cLen := len(o.TimeConfArr)
	tLen := len(o.Logs)
	var (
		surplus    uint
		surplusMap = map[int]int{}
		allowTime  time.Time
		newLogs    = []LogTime{}
	)

	o.logLock.Lock()
	defer func() {
		o.Logs = newLogs
		o.logLock.Unlock()
	}()

	if cLen > 0 && tLen > 0 {
		for i := tLen - 1; i >= 0; i-- {
			cIndex := cLen - 1
			for cIndex >= 0 {
				if o.Logs[i].Time.After(time.Now().Add(-o.TimeConfArr[cIndex].Duration)) {
					if cIndex == cLen-1 {
						newLogs = append([]LogTime{o.Logs[i]}, newLogs...)
					}
					if surplus > 0 || len(surplusMap) == 0 {
						surplusMap[cIndex] = int(o.TimeConfArr[cIndex].Count) // - (tLen - i)
						if o.Logs[i].UniqueID == uniqueID {
							surplusMap[cIndex] -= tLen - i
						}
						if surplusMap[cIndex] <= 0 {
							// 无剩余操作次数
							allowTime = o.Logs[i].Time.Add(o.TimeConfArr[cIndex].Duration)
							surplus = 0
							break
						}
						if surplusMap[cIndex] < int(surplus) || surplus == 0 {
							surplus = uint(surplusMap[cIndex])
						}
					}
					cIndex--
				} else {
					tLen = len(newLogs)
					break
				}
			}
		}
	}
	if cLen > 0 && tLen == 0 {
		surplus = o.TimeConfArr[0].Count
	}
	// allowTime.IsZero() 判断是否为初始化时间
	return uint(surplus), allowTime
}
